import group from './group';

class groupNode {
  public prev: groupNode;
  public next: groupNode;
  public content: group;
  constructor(prev: groupNode, next: groupNode, content: group) {
    this.prev = prev;
    this.next = next;
    this.content = content;
  }
  public getPrevGroup(): group {
    if (this.content === null) {
      return null;
    } else {
      return this.content;
    }
  }
  public getNextGroup(): group {
    if (this.content === null) {
      return null;
    } else {
      return this.content;
    }
  }
  public deleCurrentNode(): boolean {
    if (this.prev === null && this.next === null) {
      return false;
    }
    if (this.prev === null) {
      this.next.prev = null;
    }
    return true;
  }
  public insertLast(value: groupNode): void {
    let node = value;
    if (this.next === null) {
      node.prev = this;
      this.next = node;
    } else {
      let rNode = this.next;
      node.next = rNode;
      node.prev = this;
      this.next = node;
    }
  }
  public insertHead(value: groupNode): void {
    let node = value;
    if (this.prev === null) {
      node.next = this;
      this.prev = node;
    } else {
      let rNode = this.prev;
      node.prev = rNode;
      node.next = this;
      this.prev = node;
    }
  }
}

class groupNodeList {
  private headNode: groupNode;
  private size: number = 0;
  constructor() {
    this.headNode = new groupNode(null, null, null);
  }
  public addNode(value: group): void {
    let node = new groupNode(null, null, value);
    this.size++;
    if (this.headNode.content === null) {
      this.headNode = node;
    } else {
      let lastNode = this.findLastNode(this.headNode);
      lastNode.insertLast(node);
    }
  }
  public deleteNode(value: number): void {
    let node = this.getNode(value);
    let prev = node.prev;
    let next = node.next;
    prev.next = next;
    next.prev = prev;
    node = null;
    this.size--;
  }
  private findLastNode(value: groupNode): groupNode {
    let node = value;
    while (node.next != null) {
      node = node.next;
    }
    return node;
  }
  public getNode(value: number): groupNode {
    if (value < 0 || value > this.size - 1) {
      throw new Error(`this ${value} exceeds the data length`);
    }
    let node = this.headNode;
    while (value > 0) {
      value--;
      if (node.next != null) {
        node = node.next;
      }
    }
    return node;
  }
  public getRootNode(): groupNode {
    return this.headNode;
  }
  public getRootNodeContent(): group {
    return this.headNode.content;
  }
}

export default groupNodeList;
